﻿using System;
using System.Collections.Generic;
using System.Data.Objects.DataClasses;
using System.Linq;
using System.Threading;
using ButsaLib;
using ButsaLib.Models;
using ButsaScraperLib;
using ForecastPair = ButsaLib.Models.ForecastPair;

namespace ButsaForecast.Dialogs
{
	/// <summary>
	/// Interaction logic for LoadForecastSnapshotProgressWindow.xaml
	/// </summary>
	public partial class LoadForecastSnapshotProgressWindow
	{
		private ForecastSnapshot _forecastSnapshot;

		private List<ForecastPairRef> _forecastPairRefs = new List<ForecastPairRef>();

		private List<Team> _teams = new List<Team>();

		public LoadForecastSnapshotProgressWindow(ForecastSnapshot forecastSnapshot)
		{
			InitializeComponent();

			_forecastSnapshot = forecastSnapshot;

			LoadForecastPairs();
		}

		private void LoadForecastPairs()
		{
			Thread thread = new Thread(ThreadedForecastTableReading) { IsBackground = true };
			thread.Start();
		}

		private void ThreadedForecastTableReading()
		{
			ButsaManager.Instance.ReadForecastTableLight(ReadForecastProgress, ReadForecastCompleted);
		}

		private void ReadForecastProgress(object sender, ProgressEventArgs args)
		{
			LogMessage(String.Format("Чтение таблицы прогноза {0}% - {1}", args.CurrentProgress.ToString("0.0"), args.InfoMessage));
		}

		private void ReadForecastCompleted(object sender, ReadForecastCompletedArgs args)
		{
			_forecastPairRefs = args.ForecastPairs;

			//теперь читаем команды
			Thread thread = new Thread(ThreadedTeamsReading) { IsBackground = true };
			thread.Start();
		}

		private void ThreadedTeamsReading()
		{
			List<string> teamsIds = _forecastPairRefs.Select(item => item.HomeTeamId.ToString()).ToList();
			teamsIds.AddRange(_forecastPairRefs.Select(item => item.GuestTeamId.ToString()).ToList());
			ButsaManager.Instance.ReadTeams(teamsIds, ReadTeamsProgress, ReadTeamsCompleted);
		}

		private void ReadTeamsProgress(object sender, ProgressEventArgs args)
		{
			LogMessage(String.Format("Чтение команд {0}% - {1}", args.CurrentProgress.ToString("0.0"), args.InfoMessage));
		}

		private void ReadTeamsCompleted(object sender, ReadTeamsCompletedArgs args)
		{
			_teams = args.Teams;

			MakeSnapshot();
		}

		private void MakeSnapshot()
		{
			ButsaDbContext dbContext = MainWindow.GetDbContext();
			_forecastSnapshot = dbContext.ForecastSnapshots.First(item => item.ForecastSnapshotId == _forecastSnapshot.ForecastSnapshotId);

			foreach (var team in _teams)
			{
				TeamShot teamShot = dbContext.TeamShots.Add(new TeamShot());
				teamShot.PlayerShots = new EntityCollection<PlayerShot>();
				teamShot.CountryName = team.CountryName;
				teamShot.DivisionName = team.DivisionName;
				teamShot.Force = team.Force;
				teamShot.ForecastSnapshot = _forecastSnapshot;
				teamShot.HasManager = team.HasManager;
				teamShot.Manager = team.Manager;
				teamShot.Money = Double.Parse(team.Money.Replace(".", String.Empty).Trim());
				teamShot.Rating = team.Rating;
				teamShot.TeamId = Int32.Parse(team.TeamId.Trim());
				teamShot.TeamName = team.TeamName;
				teamShot.Top11Force = team.Top11Force;
				foreach (var player in team.Players)
				{
					PlayerShot playerShot = dbContext.PlayerShots.Add(new PlayerShot());
					playerShot.BonusShots = new EntityCollection<BonusShot>();
					playerShot.Age = player.Age;
					playerShot.CalculatedTotalSkill = player.ActualTotalSkill;
					playerShot.CurrentTotalSkill = player.CurrentTotalSkill;
					playerShot.DribblingSkill = player.DribblingSkill;
					playerShot.IsDiscvalificated = player.IsDiscvalificated;
					playerShot.IsTraumed = player.IsTraumed;
					playerShot.MarkingSkill = player.MarkingSkill;
					playerShot.Morality = player.Morality;
					playerShot.PassSkill = player.PassSkill;
					playerShot.PhysicalFitness = player.PhysicalFitness;
					playerShot.PlayerId = Int32.Parse(player.Id.Trim());
					playerShot.PlayerName = player.Name;
					playerShot.PlayerNumber = Int32.Parse(player.Number.Trim());
					playerShot.PrimaryPosition = player.PrimaryPosition.ToString();
					playerShot.SecondaryPosition = player.SecondaryPosition.ToString();
					playerShot.ReceptionSkill = player.ReceptionSkill;
					playerShot.StaminaSkill = player.StaminaSkill;
					playerShot.StrikeAccuracySkill = player.StrikeAccuracySkill;
					playerShot.StrikeValueSkill = player.StrikeValueSkill;
					playerShot.TakingSkill = player.TakingSkill;
					playerShot.TeamShot = teamShot;
					playerShot.Tiredness = player.Tiredness;

					foreach (var keyValuePair in player.BonusesList)
					{
						BonusShot bonusShot = dbContext.BonusShots.Add(new BonusShot 
							{
								BonusName = keyValuePair.Key.ToString(), 
								BonusValue = keyValuePair.Value
							});
						playerShot.BonusShots.Add(bonusShot);
						
					}
					teamShot.PlayerShots.Add(playerShot);
				}
				_forecastSnapshot.TeamShots.Add(teamShot);
			}

			foreach (var forecastPairRef in _forecastPairRefs)
			{
				ForecastPair forecastPair = dbContext.ForecastPairs.Add(new ForecastPair());
				//forecastPair.DiffForecast = forecastPairRef.DiffForecast;
				forecastPair.ForecastSnapshot = _forecastSnapshot;
				forecastPair.GuestTeamGoals = forecastPairRef.GuestTeamGoals;
				forecastPair.HomeTeamGoals = forecastPairRef.HomeTeamGoals;
				//forecastPair.GuestTeamGoalsForecast = forecastPairRef.GuestTeamGoalsForecast;
				//forecastPair.HomeTeamGoalsForecast = forecastPairRef.HomeTeamGoalsForecast;
				forecastPair.HomeTeamShot = _forecastSnapshot.TeamShots.First(item => item.TeamId == forecastPairRef.HomeTeamId);
				forecastPair.GuestTeamShot = _forecastSnapshot.TeamShots.First(item => item.TeamId == forecastPairRef.GuestTeamId);
			}

			LogMessage("Объекты для базы данных подготовлены.");
			var recordAffected = dbContext.SaveChanges();
			LogMessage(String.Format("В базе сохранено {0} записей.", recordAffected));
		}

		private void LogMessage(string message)
		{
			if (LogTextBox.Dispatcher.CheckAccess())
			{
				LogTextBox.Text = message + "\r\n" + LogTextBox.Text;
			}
			else
			{
				LogTextBox.Dispatcher.Invoke(new Action(() => LogMessage(message)), new object[] { });
			}
		}
	}
}
